package com.gmail.avereshchaga.web.transport;

import com.gmail.avereshchaga.db.entity.IInvoice;
import com.gmail.avereshchaga.db.entity.IUser;
import com.gmail.avereshchaga.db.entity.IUserSessionId;
import com.gmail.avereshchaga.db.entity.InvoiceImpl;
import com.gmail.avereshchaga.db.service.IInvoiceService;
import com.gmail.avereshchaga.db.service.IUserSessionIdService;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Class performs the functions of the controller operations entity Invoice
 *
 * @author <a href="mailto:avereshchaga@gmail.com">Vereshchaga Alexey</a>
 */
@Controller
public class InvoiceTransport {

    @Autowired
    private IInvoiceService invoiceService;
    @Autowired
    IUserSessionIdService userSessionIdService;

    /**
     * Call method of search all invoices
     *
     * @param sessionId id defines the ability to perform the method
     * @param pageStr current page of the list
     * @return list of Invoices
     */
    @RequestMapping(value = "invoicesAll")
    @ResponseBody
    public List findAll(@RequestParam("sessionId") String sessionId, @RequestParam("page") String pageStr) {
        List invoices = new ArrayList();
        if (userSessionIdService.findBySessionId(sessionId)) {
            Integer page = Integer.parseInt(pageStr);
            invoices = invoiceService.findAll(page);
        }
        return invoices;
    }

    /**
     * Call method of search by filter
     *
     * @param sessionId id defines the ability to perform the method
     * @param pageStr current page of the list
     * @param createDate date when invoice was created
     * @param createdBy name who created the invoice
     * @return list of Invoices
     */
    @RequestMapping(value = "invoicesByFilter")
    @ResponseBody
    public List findByFilter(@RequestParam("sessionId") String sessionId,
            @RequestParam("page") String pageStr,
            @RequestParam("createDate") String createDate,
            @RequestParam("createdBy") String createdBy) {
        List invoices = new ArrayList();
        Date date = null;
        if (userSessionIdService.findBySessionId(sessionId)) {
            Integer page = Integer.parseInt(pageStr);
            DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
            try {
                date = dateFormat.parse(createDate);
            } catch (ParseException ex) {
                Logger.getLogger(InvoiceTransport.class.getName()).log(Level.SEVERE, null, ex);
            }
            invoices = invoiceService.findByFilter(date, createdBy, page);
        }
        return invoices;
    }

    /**
     * Call method of search by name who created the invoice
     *
     * @param sessionId id defines the ability to perform the method
     * @param pageStr current page of the list
     * @param createdBy name who created the invoice
     * @return list of Invoices
     */
    @RequestMapping(value = "invoicesByName")
    @ResponseBody
    public List findByName(@RequestParam("sessionId") String sessionId,
            @RequestParam("page") String pageStr,
            @RequestParam("createdBy") String createdBy) {
        List invoices = new ArrayList();
        if (userSessionIdService.findBySessionId(sessionId)) {
            Integer page = Integer.parseInt(pageStr);
            invoices = invoiceService.findByName(createdBy, page);
        }
        return invoices;
    }

    /**
     * Call method of search invoice by id
     *
     * @param sessionId id defines the ability to perform the method
     * @param idStr id of the invoice
     * @return Invoice
     */
    @RequestMapping(value = "invoiceById")
    @ResponseBody
    public IInvoice findById(@RequestParam("sessionId") String sessionId, @RequestParam("id") String idStr) {
        IInvoice invoice = new InvoiceImpl();
        if (userSessionIdService.findBySessionId(sessionId)) {
            Long id = Long.parseLong(idStr);
            invoice = invoiceService.findById(id);
        }
        return invoice;
    }

    /**
     * Calls the method of create the invoice
     *
     * @param sessionId id defines the ability to perform the method
     * @param invoiceStr invoice to the creation
     * @return created Invoice
     */
    @RequestMapping(value = "createInvoice")
    @ResponseBody
    public IInvoice createInvoice(@RequestParam("sessionId") String sessionId, @RequestParam("invoice") String invoiceStr) {
        IInvoice invoice = new InvoiceImpl();
        if (userSessionIdService.findBySessionId(sessionId)) {
            IUserSessionId userSessionId = userSessionIdService.findUserBySessionId(sessionId);
            IUser user = userSessionId.getUser();
            ObjectMapper mapper = new ObjectMapper();
            try {
                invoice = mapper.readValue(invoiceStr, new TypeReference<InvoiceImpl>() {
                });
            } catch (JsonParseException ex) {
                Logger.getLogger(InvoiceItemsTransport.class.getName()).log(Level.SEVERE, null, ex);
            } catch (JsonMappingException ex) {
                Logger.getLogger(InvoiceItemsTransport.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(InvoiceItemsTransport.class.getName()).log(Level.SEVERE, null, ex);
            }
            invoice.setUser(user);
            invoice = invoiceService.createInvoice(invoice);
        }
        return invoice;
    }

    /**
     * Call method of deleting the invoice
     *
     * @param sessionId id defines the ability to perform the method
     * @param idStr invoice's id
     * @return message on the results of deleting
     */
    @RequestMapping(value = "deleteInvoice")
    @ResponseBody
    public String deleteInvoice(@RequestParam("sessionId") String sessionId, @RequestParam("id") String idStr) {
        IInvoice invoice = new InvoiceImpl();
        if (userSessionIdService.findBySessionId(sessionId)) {
            try {
                Long id = Long.parseLong(idStr);
                invoice = invoiceService.findById(id);
                invoiceService.deleteInvoice(invoice);
                return " deleted";
            } catch (Exception e) {
                return e.toString();
            }
        } else {
            return null;
        }
    }
}
